package pl.cezary.butler.walili.server.db.utils;

import java.sql.*;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.tomcat.dbcp.dbcp.DelegatingConnection;

/**
 *
 * @author Cezary Butler
 */
public final class ConnectionPool {

    private BlockingQueue<Connection> dostepne;
    private Set<Connection> wszystkie;

    public ConnectionPool() {
        dostepne = new LinkedBlockingDeque<Connection>();
        wszystkie = new CopyOnWriteArraySet<Connection>();
    }

    public ConnectionPool(Collection<Connection> c) {
        this();
        dodajPolaczenie(c);
    }

    public synchronized void dodajPolaczenie(Connection c) {
        dostepne.add(c);
        wszystkie.add(c);
    }

    public synchronized void dodajPolaczenie(Collection<Connection> c) {
        dostepne.addAll(c);
        wszystkie.addAll(c);
    }

    private class PooledConnectionWrapper extends DelegatingConnection implements Connection{
        
        PooledConnectionWrapper(Connection c){
            super(c);
        }
        
        @Override
        public void close(){
           zwroc(_conn);
        }

        Connection getConn() {
            return _conn;
        }
        
        
        
    }
    
    public Connection podaj() {
        return new PooledConnectionWrapper(dostepne.poll());
    }

    void zwroc(Connection c) {        
        if (wszystkie.contains(c)) {
            dostepne.offer(c);
        }
    }

    public void zamknij() {
        new Thread("Closeing connection pool") {

            @Override
            public void run() {
                for (int i = 0; i < wszystkie.size(); ++i) {
                    try {
                        podaj().close();
                    } catch (SQLException ex) {
                        Logger.getLogger(ConnectionPool.class.getName()).log(Level.SEVERE, "There was a problem during closing a database connection.", ex);
                    }
                }
                wszystkie.clear();
                dostepne.clear();
            }
        }.start();
    }
}
